#include <iostream>
#include <cstring>
#include <cassert>

class My_string
{
public:
    My_string(const char* str = "")
    : _str(new char[strlen(str) + 1])
    , _size(strlen(str))
    {
        strcpy(_str, str);
    }

    void swap(My_string& s)
	{
		std::swap(_str, s._str);
		std::swap(_size, s._size);
	}
    // 拷贝构造
    My_string(const My_string& s)
    : _str(nullptr)
    {
        std::cout << "My_string(const My_string& s) -- 深拷贝" << std::endl;
        // _str = new char[strlen(s._str) + 1];
        // strcpy(_str, s._str);
        My_string tmp(s._str);
        std::swap(_str, tmp._str);
    }
    // 移动构造
    My_string(My_string&& s)
    : _str(nullptr)
    {
        std::cout << "My_string(My_string&& s)" << std::endl;
        swap(s);
    }
    // 赋值重载
    My_string& operator=(const My_string& s)
    {
        std::cout << "My_string& operator=(const My_string& s) -- 深拷贝赋值" << std::endl;
        if(this != &s)
        {
            // My_string tmp(s);
			// swap(tmp);
            char* pstr = new char[strlen(s._str) + 1];
            strcpy(pstr, s._str);
            delete[] _str;
            _str = pstr;
        }
        return *this;
    }

    My_string& operator=(My_string&& s)
    {
        std::cout << "My_string& operator=(My_string&& s) -- 移动赋值" << std::endl;
        swap(s);
        return *this;
    }

    const char* c_str()
    {
        return _str;
    }

    char& operator[](size_t pos)
	{
		assert(pos < _size);
		return _str[pos];
	}

    ~My_string()
    {
        if(_str)
        {
            delete[] _str;
            _str = nullptr;
        }
    }
private:
    char* _str;
    size_t _size;
};


